package com.nx.platform.es.biz.esspider.resource;


import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.nx.platform.es.common.utils.RSAUtil;
import com.nx.platform.es.common.utils.YamlParser;
import com.nx.platform.es.system.config.ConfigCenter;
import com.nx.platform.es.common.utils.MoreMaps;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author
 * @date 2018/01/25
 */
public class DBManagerImpl implements DBManager {

    private static final String ID = "id";

    private final String configFilePath;
    private final String configKey;

    private Map<String, DBResource> dbResourceMap = null;

    public DBManagerImpl(String configFilePath, String configKey) {
        this.configFilePath = configFilePath;
        this.configKey = configKey;
    }

    public NamedParameterJdbcTemplate acquireJdbcTemplate(String id) {
        if (dbResourceMap == null) {
            synchronized (this) {
                if (dbResourceMap == null) {
                    String settings = ConfigCenter.getConfig(configKey).orElse("");
                    dbResourceMap = dbResourceMap(RSAUtil.decodeDBConf(settings));
                }
            }
        }
        Preconditions.checkArgument(id != null && dbResourceMap.containsKey(id),
                "db not registered yet, id: " + id);
        return dbResourceMap.get(id).getJdbcTemplate();
    }

    public void close() {
        dbResourceMap.values().forEach(DBResource::releaseJdbcTemplate);
    }

    private Map<String, DBResource> dbResourceMap(String settings) {
        List<Map<?, ?>> list = YamlParser.parseToList(settings);
        Preconditions.checkState(!list.isEmpty(), "db resource empty");
        return list.stream().map(m -> {
            String id = MoreMaps.getString(m, ID);
            Preconditions.checkArgument(!Strings.isNullOrEmpty(id), "db id null or empty, id: " + id);
            return new DBResource(configFilePath, id, m);
        }).collect(Collectors.toMap(DBResource::getId, Function.identity()));
    }

}
